﻿using System;

namespace TestArchitecture
{
    public interface IDrawableNumber
    {
        void Draw(IDrawer drawer);
        void SetValue(double value);
        double GetValue();
    }

    public abstract class Decorator : IDrawableNumber
    {
        private IDrawableNumber _child;

        public Decorator()
        {
        }

        public Decorator(IDrawableNumber child)
        {
            _child = child;
        }

        protected IDrawableNumber Child 
        {
            get { return _child; }
            set { _child = value; }
        }

        public virtual void Draw(IDrawer drawer)
        {
            Child.Draw(drawer);
        }

        public virtual void SetValue(double value)
        {
            Child.SetValue(value);
        }

        public virtual double GetValue()
        {
            return Child.GetValue();
        }
    }

    public class SqrtDrawableNumber : IDrawableNumber
    {
        private double _value;

        public SqrtDrawableNumber(double value)
        {
            _value = value;
        }

        public void Draw(IDrawer drawer)
        {
            double value = GetValue();
            double sqrt = Math.Sqrt(value);
            drawer.DrawValue(sqrt);
        }

        public void SetValue(double value)
        {
            _value = value;
        }

        public virtual double GetValue()
        {
            return _value;
        }
    }




    public class AbsDrawableNumberDecorator : Decorator
    {
        public AbsDrawableNumberDecorator(IDrawableNumber child) : base(child)
        {
        }

        public override double GetValue()
        {
            double tmp = base.GetValue();
            if (tmp < 0)
                return -1.0*tmp;
            return tmp;
        }
    }


    class Program
    {
        private static void Main()
        {
            IDrawableNumber decorator = new AbsDrawableNumberDecorator(new SqrtDrawableNumber(-16.0));

            decorator.Draw(new BracketsDrawer());
            decorator.Draw(new QuotesDrawer());
        }
    }
}